"""
日志模块，提供统一的日志配置和获取方法
"""
import logging
import os
import time
from datetime import datetime
from functools import wraps

# 日志级别映射
LOG_LEVELS = {
    'debug': logging.DEBUG,
    'info': logging.INFO,
    'warning': logging.WARNING,
    'error': logging.ERROR,
    'critical': logging.CRITICAL
}

class LoggerFactory:
    """
    日志工厂类，负责创建和配置日志记录器
    """
    _initialized = False
    _log_dir = None
    _default_level = logging.INFO
    _format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    
    @classmethod
    def initialize(cls, log_dir=None, level='info', format=None):
        """
        初始化日志系统
        
        参数:
            log_dir: 日志文件存储目录，默认为项目根目录下的logs文件夹
            level: 日志级别，可选值为debug, info, warning, error, critical
            format: 日志格式
        """
        # 设置日志目录
        if log_dir is None:
            # 默认日志目录为项目根目录下的logs文件夹
            project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
            cls._log_dir = os.path.join(project_root, 'logs')
        else:
            cls._log_dir = log_dir
            
        # 确保日志目录存在
        os.makedirs(cls._log_dir, exist_ok=True)
        
        # 设置日志级别
        if level in LOG_LEVELS:
            cls._default_level = LOG_LEVELS[level]
            
        # 设置日志格式
        if format is not None:
            cls._format = format
            
        cls._initialized = True
    
    @classmethod
    def get_logger(cls, name, filename=None, level=None, console_level=logging.WARNING):
        """
        获取日志记录器
        
        参数:
            name: 日志记录器名称
            filename: 日志文件名，默认为{name}.log
            level: 日志级别，默认使用初始化时设置的级别
            console_level: 控制台日志级别，默认为 WARNING
            
        返回:
            logger: 配置好的日志记录器
        """
        # 导入必要的模块
        import logging
        import logging.handlers
        import os
        from datetime import datetime
        
        # 如果未初始化，则使用默认配置初始化
        if not cls._initialized:
            cls.initialize()
            
        # 创建日志记录器
        logger = logging.getLogger(name)
        
        # 设置日志级别
        if level is not None and level in LOG_LEVELS:
            logger.setLevel(LOG_LEVELS[level])
        else:
            logger.setLevel(cls._default_level)
        
        # 避免日志传播到根记录器
        logger.propagate = False
            
        # 清除现有处理器
        for handler in logger.handlers[:]:
            logger.removeHandler(handler)
            
        # 创建控制台处理器 - 仅显示 WARNING 及以上级别
        console_handler = logging.StreamHandler()
        console_handler.setLevel(console_level)  # 只显示 WARNING 及以上级别
        console_format = logging.Formatter('%(levelname)s - %(name)s - %(message)s')
        console_handler.setFormatter(console_format)
        logger.addHandler(console_handler)
            
        # 设置日志文件名
        if filename is None:
            filename = f"{name}.log"
                
        log_file = os.path.join(cls._log_dir, filename)
            
        # 创建文件处理器，使用 RotatingFileHandler 支持日志轮转
        try:
            file_handler = logging.handlers.RotatingFileHandler(
                log_file, maxBytes=10*1024*1024, backupCount=5, encoding='utf-8')
        except (ImportError, AttributeError):
            # 如果不支持 RotatingFileHandler，则使用普通的 FileHandler
            file_handler = logging.FileHandler(log_file, encoding='utf-8')
            
        file_handler.setLevel(logger.level)
            
        # 设置日志格式
        formatter = logging.Formatter(cls._format)
        file_handler.setFormatter(formatter)
            
        # 添加处理器到日志记录器
        logger.addHandler(file_handler)
        
        return logger

# 提供便捷的获取日志记录器的方法
def get_logger(name, filename=None, level=None):
    """
    获取日志记录器的便捷方法
    
    参数:
        name: 日志记录器名称
        filename: 日志文件名，默认为{name}_{当前时间}.log
        level: 日志级别，默认使用初始化时设置的级别
        
    返回:
        logger: 配置好的日志记录器
    """
    return LoggerFactory.get_logger(name, filename, level)

# 提供便捷的初始化日志系统的方法
def initialize_logging(log_dir=None, level='info', format=None):
    """
    初始化日志系统的便捷方法
    
    参数:
        log_dir: 日志文件存储目录，默认为项目根目录下的logs文件夹
        level: 日志级别，可选值为debug, info, warning, error, critical
        format: 日志格式
    """
    LoggerFactory.initialize(log_dir, level, format)

def run_time(func):
    """
    统计函数运行时间的装饰器
    
    参数:
        func: 被装饰的函数
        
    返回:
        wrapper: 包装后的函数
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        logger = get_logger('run_time')
        start_time = time.time()
        try:
            result = func(*args, **kwargs)
            end_time = time.time()
            elapsed = (end_time - start_time) * 1000  # 转换为毫秒
            logger.info(f"函数 {func.__name__} 运行时间: {elapsed:.2f}ms")
            return result
        except Exception as e:
            end_time = time.time()
            elapsed = (end_time - start_time) * 1000
            logger.error(f"函数 {func.__name__} 运行出错，已运行时间: {elapsed:.2f}ms, 错误: {str(e)}")
            raise
    
    return wrapper